{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9d3177e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import requests\n",
    "from bs4 import BeautifulSoup\n",
    "import base64\n",
    "import re\n",
    "import io\n",
    "import cv2\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "76ec9952",
   "metadata": {},
   "outputs": [],
   "source": [
    "def base64_encode(s: str):\n",
    "    return base64.encodebytes(s.encode()).decode('utf-8')\n",
    "\n",
    "def base64_decode(s: str):\n",
    "    return base64.decodebytes(s.encode()).decode('utf-8')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d2665a39",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('plant.json', 'r', encoding='utf-8') as fp:\n",
    "    plant = json.load(fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f2663fda",
   "metadata": {},
   "outputs": [],
   "source": [
    "for a in plant.values():\n",
    "    for b in a:\n",
    "        if '植' in b['name']:\n",
    "            b['name'] = b['information']['基本信息']['中文名称']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d1b327d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "plant_name = [b['name'] for a in plant.values() for b in a]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "368f8ea1",
   "metadata": {},
   "outputs": [],
   "source": [
    "resp = requests.get('https://www.plantplus.cn/cn/sp/%E8%82%8B%E6%9E%9C%E8%8C%B6')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2414a6d5",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "肋果茶\n",
      "蒜头木\n",
      "list index out of range\n",
      "榨木\n",
      "list index out of range\n",
      "南洋杉\n",
      "红果冬青\n",
      "幌伞枫\n",
      "洋蒲桃\n",
      "广玉兰\n",
      "八角\n",
      "云南松\n",
      "柏树\n",
      "深山含笑\n",
      "晚春含笑\n",
      "list index out of range\n",
      "蒜头果\n",
      "蓑衣油杉\n",
      "list index out of range\n",
      "多花含笑\n",
      "桢楠\n",
      "荷木\n",
      "日本珊瑚树\n",
      "杨梅\n",
      "窄叶枇杷\n",
      "香叶树\n",
      "柑橘\n",
      "香叶树\n",
      "北美红杉\n",
      "白栎\n",
      "滇油杉\n",
      "list index out of range\n",
      "华山松\n",
      "麻楝\n",
      "茶梅\n",
      "藏柏\n",
      "云南山茶花\n",
      "list index out of range\n",
      "杉木\n",
      "蒲葵\n",
      "柳杉\n",
      "红叶石楠\n",
      "清香木\n",
      "龙柏\n",
      "檵木\n",
      "红千层\n",
      "千层金\n",
      "木麻黄\n",
      "澳洲火焰木\n",
      "大叶女贞\n",
      "金沙槭\n",
      "云南栘\n",
      "list index out of range\n",
      "云南红豆杉\n",
      "杨桐\n",
      "小叶冬青\n",
      "list index out of range\n",
      "长梗润楠\n",
      "高山榕\n",
      "白兰\n",
      "球花含笑\n",
      "银荆\n",
      "红花木莲\n",
      "云南拟单性木兰\n",
      "枇杷\n",
      "深山含笑\n",
      "天竺桂\n",
      "小叶榕\n",
      "白玉兰\n",
      "杜英\n",
      "垂榕\n",
      "野桂花\n",
      "滇润楠\n",
      "昆明海桐\n",
      "山玉兰\n",
      "枸骨\n",
      "牛筋条\n",
      "木犀榄\n",
      "list index out of range\n",
      "毒药树\n",
      "桂花\n",
      "尖叶木犀榄\n",
      "list index out of range\n",
      "雪松\n",
      "雪松\n",
      "雪松\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "香樟\n",
      "乐昌含笑\n",
      "罗汉松\n",
      "椤木石楠\n",
      "荷花玉兰\n",
      "球花石楠\n",
      "流苏\n",
      "枫杨\n",
      "老虎楝\n",
      "中山杉\n",
      "石榴\n",
      "构树\n",
      "黄葛树\n",
      "日本晚樱\n",
      "樱桃\n",
      "杜仲\n",
      "李子\n",
      "list index out of range\n",
      "香椿\n",
      "梧桐\n",
      "臭椿\n",
      "花椒\n",
      "连香树\n",
      "山胡椒\n",
      "龙爪柳\n",
      "龙爪槐\n",
      "珙桐\n",
      "二乔木兰\n",
      "皱皮木瓜\n",
      "鹅耳枥\n",
      "杏\n",
      "苦楝\n",
      "柿\n",
      "碧桃\n",
      "绿宝树\n",
      "list index out of range\n",
      "桑\n",
      "无花果\n",
      "红叶碧桃\n",
      "五味子\n",
      "乌桕\n",
      "桤木\n",
      "红枫\n",
      "垂柳\n",
      "木芙蓉\n",
      "云南紫荆\n",
      "青榨槭\n",
      "泡桐\n",
      "苹果\n",
      "红叶杨\n",
      "list index out of range\n",
      "水杉\n",
      "山楂树\n",
      "list index out of range\n",
      "蓝花楹\n",
      "梓树\n",
      "刺桐\n",
      "鸡冠刺桐\n",
      "紫薇\n",
      "栾树\n",
      "栀子皮\n",
      "梅\n",
      "木棉\n",
      "滇楸\n",
      "君迁子\n",
      "紫叶李\n",
      "皂角树\n",
      "黄连木\n",
      "黄连木\n",
      "四照花\n",
      "色木槭\n",
      "重阳木\n",
      "元宝枫\n",
      "鸡爪槭\n",
      "滇合欢\n",
      "紫玉兰\n",
      "无患子\n",
      "喜树\n",
      "榉树\n",
      "垂丝海棠\n",
      "枫香树\n",
      "枫香树\n",
      "银杏\n",
      "滇朴\n",
      "list index out of range\n",
      "冬樱花\n",
      "云南樱花\n",
      "马醉木\n",
      "金叶女贞\n",
      "刺五加\n",
      "台湾胡椒木\n",
      "list index out of range\n",
      "仙人掌\n",
      "大花曼陀罗\n",
      "list index out of range\n",
      "玫瑰\n",
      "洒金珊瑚\n",
      "金叶黄杨\n",
      "鳞斑荚蒾\n",
      "迷迭香\n",
      "金丝桃\n",
      "紫绒鼠尾草\n",
      "list index out of range\n",
      "火棘\n",
      "小叶女贞\n",
      "鹅掌柴\n",
      "云南黄素馨\n",
      "黄叶假连翘\n",
      "list index out of range\n",
      "金森女贞\n",
      "亮叶忍冬\n",
      "小叶栀子\n",
      "珊瑚樱\n",
      "大叶栀子\n",
      "list index out of range\n",
      "金边黄杨\n",
      "丽蚌草\n",
      "list index out of range\n",
      "肾蕨\n",
      "八角金盘\n",
      "马缨丹\n",
      "六月雪\n",
      "萼距花\n",
      "马醉木\n",
      "金叶女贞\n",
      "南天竹\n",
      "海桐\n",
      "贴梗海棠\n",
      "文母\n",
      "list index out of range\n",
      "日本花柏\n",
      "云南含笑\n",
      "大叶黄杨\n",
      "龟甲冬青\n",
      "非洲茉莉\n",
      "叶子花\n",
      "毛叶丁香\n",
      "云南丁香\n",
      "棕竹\n",
      "龟背竹\n",
      "蜡梅\n",
      "朱槿\n",
      "美丽针葵\n",
      "苏铁\n",
      "胡颓子\n",
      "黄花槐\n",
      "夹竹桃\n",
      "南天竹\n",
      "金叶六道木\n",
      "栒子\n",
      "杜鹃\n",
      "欧洲荚蒾\n",
      "木槿\n",
      "红花檵木\n",
      "丽蚌草\n",
      "list index out of range\n",
      "海芋\n",
      "日中花\n",
      "龙舌兰\n",
      "藿香\n",
      "鸡冠花\n",
      "旅人蕉\n",
      "地涌金莲\n",
      "菖蒲\n",
      "金盏菊\n",
      "花叶美人蕉\n",
      "list index out of range\n",
      "马蹄莲\n",
      "美人蕉\n",
      "火炬花\n",
      "马蹄莲\n",
      "花叶良姜\n",
      "洒金桃叶珊瑚\n",
      "孔雀草\n",
      "苦丁茶\n",
      "紫花地丁\n",
      "红叶朱蕉\n",
      "list index out of range\n",
      "一串红\n",
      "蜘蛛兰\n",
      "孔雀草\n",
      "吊兰\n",
      "葱莲\n",
      "春羽\n",
      "血苋\n",
      "红花醡浆草\n",
      "list index out of range\n",
      "芭蕉\n",
      "矮小沿阶草\n",
      "麦冬\n",
      "薰衣草\n",
      "花叶蔓长春\n",
      "凌霄\n",
      "常春油麻藤\n",
      "猕猴桃\n",
      "蔷薇\n",
      "大血藤\n",
      "地石榴\n",
      "蝴蝶藤\n",
      "炮仗花\n",
      "常春藤\n",
      "金银花\n",
      "旱伞草\n",
      "鸢尾\n",
      "荷花\n",
      "纸莎草\n",
      "花叶芦苇\n",
      "再力花\n",
      "睡莲\n",
      "香菇草\n",
      "芦苇\n",
      "中东海枣\n",
      "list index out of range\n",
      "棕榈\n",
      "老人葵\n",
      "加拿利海枣\n",
      "方竹\n",
      "斑竹\n",
      "黄条金刚竹\n",
      "人面竹\n",
      "黄金间碧竹\n",
      "紫竹\n",
      "筇竹\n",
      "慈竹\n",
      "毛竹\n",
      "香竹\n",
      "凤尾竹\n",
      "江山倭竹\n",
      "翠竹\n",
      "金竹\n"
     ]
    }
   ],
   "source": [
    "headers = {\n",
    "    'Accept': 'text/plain, */*; q=0.01',\n",
    "    'Accept-Encoding': 'gzip, deflate, br, zstd',\n",
    "    'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7',\n",
    "    'Connection': 'keep-alive',\n",
    "    'Cookie': 'ASP.NET_SessionId=txn5gsxebgeltup3oklwkjwi; _pk_ref.4.3a6f=%5B%22%22%2C%22%22%2C1709366075%2C%22https%3A%2F%2Fwww.google.com%2F%22%5D; _pk_id.4.3a6f=e0c884c111037398.1709366075.; _pk_ses.4.3a6f=1',\n",
    "    'Host': 'www.plantplus.cn',\n",
    "    'Referer': 'https://www.plantplus.cn/cn/sp/%E8%82%8B%E6%9E%9C%E8%8C%B6',\n",
    "    'Sec-Fetch-Dest': 'empty',\n",
    "    'Sec-Fetch-Mode': 'cors',\n",
    "    'Sec-Fetch-Site': 'same-origin',\n",
    "    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',\n",
    "    'X-Requested-With': 'XMLHttpRequest',\n",
    "    'sec-ch-ua': '\"Chromium\";v=\"122\", \"Not(A:Brand\";v=\"24\", \"Google Chrome\";v=\"122\"',\n",
    "    'sec-ch-ua-mobile': '?0',\n",
    "    'sec-ch-ua-platform': '\"macOS\"'\n",
    "}\n",
    "\n",
    "has_result = []\n",
    "for name in plant_name:\n",
    "    print(name)\n",
    "    resp1 = requests.get(f'https://www.plantplus.cn/ashx/searchautocomplete.ashx?query={name}', headers=headers)\n",
    "    try:\n",
    "        if resp.text and resp1.json()['suggestions'][0]['value'] == name:\n",
    "            has_result.append(name)\n",
    "    except Exception as e:\n",
    "        print(e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2dcb13e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "has_result = list(set(has_result))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "3a001942",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 植物信息\n",
    "plantinfo_url = 'https://www.plantplus.cn/ashx/plantinfo.ashx'\n",
    "\n",
    "def get_plantinfo(data):\n",
    "    t = {}\n",
    "    for e in requests.post(plantinfo_url, data=data, headers=headers).json():\n",
    "        if e['hasdesc']:\n",
    "            t[e['t']] = base64_decode(e['desc'])\n",
    "    return t\n",
    "\n",
    "def get_plantinfo_data(spno):\n",
    "    return [\n",
    "        {\n",
    "            'name': '物种名片',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '1', \n",
    "                'subcount': '0'\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            'name': '物种保护',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '42', \n",
    "                'subcount': '6'\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            'name': '分类信息',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '21', \n",
    "                'subcount': '9'\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            'name': '形态特征',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '11', \n",
    "                'subcount': '18'\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            'name': '生态习性',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '12', \n",
    "                'subcount': '7'\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            'name': '功用价值',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '20', \n",
    "                'subcount': '4'\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            'name': '基因序列',\n",
    "            'data': {\n",
    "                'spid': spno, \n",
    "                'type': 'descjarr', \n",
    "                'typeid': '48', \n",
    "                'subcount': '0'\n",
    "            }\n",
    "        }\n",
    "    ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "88555176",
   "metadata": {},
   "outputs": [],
   "source": [
    "species = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f09a9f2f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "紫竹\n",
      "棕竹\n",
      "无患子\n",
      "栒子\n",
      "杜英\n",
      "纸莎草\n",
      "昆明海桐\n",
      "石榴\n",
      "常春藤\n",
      "黄金间碧竹\n",
      "龙柏\n",
      "榉树\n",
      "刺五加\n",
      "银杏\n",
      "连香树\n",
      "黄连木\n",
      "洋蒲桃\n",
      "金沙槭\n",
      "柑橘\n",
      "枫香树\n",
      "龙爪柳\n",
      "柳杉\n",
      "高山榕\n",
      "华山松\n",
      "杨梅\n",
      "珙桐\n",
      "长梗润楠\n",
      "金叶女贞\n",
      "桤木\n",
      "鹅耳枥\n",
      "花叶芦苇\n",
      "肾蕨\n",
      "日本晚樱\n",
      "龙舌兰\n",
      "梅\n",
      "杜鹃\n",
      "美人蕉\n",
      "方竹\n",
      "多花含笑\n",
      "杏\n",
      "麻楝\n",
      "人面竹\n",
      "栀子皮\n",
      "幌伞枫\n",
      "垂丝海棠\n",
      "金边黄杨\n",
      "红叶碧桃\n",
      "桑\n",
      "木槿\n",
      "重阳木\n",
      "鸢尾\n",
      "金森女贞\n",
      "梧桐\n",
      "紫叶李\n",
      "黄花槐\n",
      "迷迭香\n",
      "斑竹\n",
      "珊瑚樱\n",
      "碧桃\n",
      "欧洲荚蒾\n",
      "薰衣草\n",
      "日中花\n",
      "慈竹\n",
      "柿\n",
      "杨桐\n",
      "亮叶忍冬\n",
      "蝴蝶藤\n",
      "雪松\n",
      "凤尾竹\n",
      "叶子花\n",
      "小叶女贞\n",
      "蜡梅\n",
      "鸡冠刺桐\n",
      "紫玉兰\n",
      "金竹\n",
      "夹竹桃\n",
      "马蹄莲\n",
      "旅人蕉\n",
      "芦苇\n",
      "球花石楠\n",
      "苏铁\n",
      "云南松\n",
      "云南含笑\n",
      "葱莲\n",
      "银荆\n",
      "马醉木\n",
      "无花果\n",
      "地涌金莲\n",
      "杜仲\n",
      "四照花\n",
      "清香木\n",
      "海芋\n",
      "朱槿\n",
      "喜树\n",
      "龙爪槐\n",
      "肋果茶\n",
      "鸡爪槭\n",
      "香竹\n",
      "香椿\n",
      "乌桕\n",
      "红枫\n",
      "鳞斑荚蒾\n",
      "加拿利海枣\n",
      "檵木\n",
      "茶梅\n",
      "枇杷\n",
      "滇润楠\n",
      "日本珊瑚树\n",
      "云南拟单性木兰\n",
      "乐昌含笑\n",
      "青榨槭\n",
      "棕榈\n",
      "球花含笑\n",
      "红千层\n",
      "马缨丹\n",
      "筇竹\n",
      "白兰\n",
      "龟背竹\n",
      "大叶黄杨\n",
      "花椒\n",
      "红花檵木\n",
      "龟甲冬青\n",
      "白栎\n",
      "毛竹\n",
      "黄条金刚竹\n",
      "血苋\n",
      "枸骨\n",
      "鹅掌柴\n",
      "日本花柏\n",
      "木芙蓉\n",
      "中山杉\n",
      "苹果\n",
      "蓝花楹\n",
      "火炬花\n",
      "窄叶枇杷\n",
      "蒜头果\n",
      "南天竹\n",
      "蒲葵\n",
      "吊兰\n",
      "萼距花\n",
      "天竺桂\n",
      "红花木莲\n",
      "垂柳\n",
      "枫杨\n",
      "凌霄\n",
      "紫薇\n",
      "云南丁香\n",
      "深山含笑\n",
      "胡颓子\n",
      "金叶黄杨\n",
      "八角金盘\n"
     ]
    }
   ],
   "source": [
    "for name in has_result:\n",
    "    print(name)\n",
    "    t = {}\n",
    "    \n",
    "    resp = requests.get(f'https://www.plantplus.cn/cn/sp/{name}', headers=headers)\n",
    "    sp = BeautifulSoup(resp.text)\n",
    "    spno = re.findall('.*?var spno = \"([0-9]+)\";.*', sp.select('script')[7].get_text(strip=True))[0]\n",
    "    \n",
    "    # 俗名\n",
    "    popular_name = [e.get_text(strip=True) for e in \n",
    "                    sp.select('div.infotitlediv > div:nth-child(5) > div:nth-child(1) a')]\n",
    "\n",
    "    # 异名\n",
    "    synonyms = [e.get_text(strip=True) for e in \n",
    "                sp.select('div.infotitlediv > div:nth-child(5) > div.sync a')]\n",
    "    \n",
    "    # 拉丁名\n",
    "    getsplatin_url = 'https://www.plantplus.cn/ashx/getsplatin.ashx'\n",
    "    data = {'spno': spno}\n",
    "    resp = requests.post(getsplatin_url, data=data, headers=headers)\n",
    "    assert resp.text.strip() != ''\n",
    "    latin_name = ' '.join([e.get_text(strip=True) for e in BeautifulSoup(resp.text).select('.font20')])\n",
    "    \n",
    "    # 植物信息\n",
    "    for e in get_plantinfo_data(spno):\n",
    "        data = get_plantinfo(e['data'])\n",
    "        if e['name'] == '物种名片' and len(data) > 0:\n",
    "            t[e['name']] = data['物种名片']\n",
    "        else:\n",
    "            t[e['name']] = data\n",
    "            \n",
    "    # 图像信息\n",
    "#     image_url = 'https://www.plantplus.cn/ashx/getotherinfo.ashx'\n",
    "#     params = {'callbackparam': '_'}\n",
    "#     data = {'type': 'outphotoinfo', 'cid': spno}\n",
    "#     resp = requests.post(image_url, params=params, data=data, headers=headers)\n",
    "#     if resp.text.strip() != '':\n",
    "#         resp = json.loads(resp.text[2:-1])[0]\n",
    "#         if resp.get('plist', None) is not None:\n",
    "#             images = [f'https://www.plantplus.cn/ppbcimg/148/{e[\"pidmd5\"]}.jpg' for e in resp['plist']]\n",
    "#             images = [requests.get(e, headers=headers).content for e in images]\n",
    "#             images = [cv2.imdecode(np.asarray(bytearray(e), dtype=np.uint8), cv2.IMREAD_COLOR) for e in images]\n",
    "#             new_image = np.ones((452, 452, 3), np.uint8) * 255\n",
    "#             new_image[:300, :, :] = cv2.resize(images[0], (452, 300), interpolation=cv2.INTER_LANCZOS4)\n",
    "#             new_image[304:, :148, :] = images[1]\n",
    "#             new_image[304:, 148 + 4: 148 * 2 + 4, :] = images[2]\n",
    "#             new_image[304:, 148 * 2 + 8:, :] = images[3]\n",
    "#             cv2.imwrite(f'image/{name}.jpg', new_image)\n",
    "#             t['cover'] = f'image/{name}.jpg'\n",
    "    \n",
    "    # 分类\n",
    "    getcol_url = 'https://www.plantplus.cn/ashx/getcol.ashx'\n",
    "    params = {'name': base64.encodebytes(latin_name.encode()).decode().strip()}\n",
    "    resp = requests.get(getcol_url, params=params, headers=headers)\n",
    "    if resp.text.strip() != '' and resp.json().get('data', None) is not None:\n",
    "        resp = resp.json()['data']\n",
    "        t['名称 & 分类'] = {\n",
    "            '学名': f'{resp[\"scientificName\"]} ({resp[\"author\"]})',\n",
    "            '中文名': f'{resp[\"chineseName\"]} ({resp[\"chineseName_py\"]})',\n",
    "            '异名': synonyms,\n",
    "            '别名': popular_name,\n",
    "            '分布地': resp[\"Distribution_c\"],\n",
    "            '分类系统': {\n",
    "                '界': f'{resp[\"taxonTree\"][\"kingdom_c\"]} ({resp[\"taxonTree\"][\"kingdom\"]})',\n",
    "                '门': f'{resp[\"taxonTree\"][\"phylum_c\"]} ({resp[\"taxonTree\"][\"phylum\"]})',\n",
    "                '纲': f'{resp[\"taxonTree\"][\"class_c\"]} ({resp[\"taxonTree\"][\"class\"]})',\n",
    "                '目': f'{resp[\"taxonTree\"][\"order_c\"]} ({resp[\"taxonTree\"][\"order\"]})',\n",
    "                '科': f'{resp[\"taxonTree\"][\"family_c\"]} ({resp[\"taxonTree\"][\"family\"]})',\n",
    "                '属': f'{resp[\"taxonTree\"][\"genus_c\"]} ({resp[\"taxonTree\"][\"genus\"]})',\n",
    "            },\n",
    "            '文献': [e[f'[{i + 1}]'] for i, e in enumerate(resp[\"Refs\"])]\n",
    "        }\n",
    "    \n",
    "    # 植物志\n",
    "    getfrps_url = 'https://www.plantplus.cn/ashx/getfrps.ashx'\n",
    "    params = {'key': latin_name}\n",
    "    resp = requests.get(getfrps_url, params=params, headers=headers)\n",
    "    if resp.text.strip() != '':\n",
    "        cited = [e.get_text(strip=True) for e in BeautifulSoup(resp.json()['frpsnolink']).children]\n",
    "        cited.append(f'{name} {latin_name}')\n",
    "        cited = ' >> '.join(filter(lambda e: e not in ('', 'PDF'), cited))\n",
    "        paragraph = [e.get_text(strip=True) for e in BeautifulSoup(resp.json()['frpsdesc']).children]\n",
    "        t['植物志'] = {\n",
    "            '标题': cited,\n",
    "            '正文': paragraph\n",
    "        }\n",
    "    \n",
    "    # 标本分布\n",
    "    spmapplacegroup_url = 'https://www.plantplus.cn/cvh/ashx/spmapplacegroup.ashx'\n",
    "    params = {'key': latin_name, 'callbackparam': '_'}\n",
    "    resp = requests.get(spmapplacegroup_url, params=params, headers=headers)\n",
    "    if resp.text.strip() != '':\n",
    "        resp = json.loads(resp.text[2:-1])[0]\n",
    "        if resp.get('mplace', None) is not None:\n",
    "            t['标本分布'] = resp['mplace'].split('，')\n",
    "    \n",
    "    species[name] = t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "524f6d6a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "151"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(species)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "3c80da75",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('species.json', 'w', encoding='utf-8') as fp:\n",
    "    json.dump(species, fp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a5bf1611",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch-env",
   "language": "python",
   "name": "pytorch-env"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
